import { BaseCommand, cadAppLog, CSLine } from '@amcax/base';
import { ctx2, dataManager, docMgr } from '@app-cad/module';
import { message } from 'antd';
import { Object3D, Vector3 } from 'three-legacy';

export const TOPOLOGY_OBJECT_NAME = 'topologyParent';
export const clearTopologyGroup = () => {
  const target = ctx2.cadScene.toolsGroup.children.find(
    (o) => o.name === TOPOLOGY_OBJECT_NAME,
  );

  if (target != null) {
    ctx2.cadScene.toolsGroup.remove(target);
  }
};

let isChecked = false;

const checkTopology = () => {
  if (!isChecked) {
    message.loading({ content: '拓扑检查中...', key: 'checkTopology' });
    clearTopologyGroup();
    const objects = docMgr.flatDocumentObjects;
    cadAppLog('checkTopology[objects]', objects);

    const topologyObject = new Object3D();
    topologyObject.name = TOPOLOGY_OBJECT_NAME;
    ctx2.cadScene.toolsGroup.add(topologyObject);

    for (const obj of objects) {
      if (obj.visibility) {
        // not used in assembly environment, no partKey
        const vData = dataManager.getShapeData(obj.dxid);
        cadAppLog('checkTopology[vData]', vData);
        if (vData && vData.faces && vData.faces.length > 0) {
          const edgeCountHolder = {};
          for (let i = 0; i < vData.faces.length; i++) {
            const faceEdges = vData.faces[i]['edges'];
            for (let j = 0; j < faceEdges.length; j++) {
              if (!edgeCountHolder[faceEdges[j]]) {
                edgeCountHolder[faceEdges[j]] = 1;
              } else {
                edgeCountHolder[faceEdges[j]] += 1;
              }
            }
          }
          cadAppLog('checkTopology[edgeCountHolder]', edgeCountHolder);
          for (const key in edgeCountHolder) {
            //
            if (edgeCountHolder[key] === 1) {
              // 边只被引用1次，显示红色
              drawEdge(vData.edges[key].mesh, 0xfe3535, topologyObject);
            } else if (edgeCountHolder[key] === 2) {
              // 被应用2次，说明是共边，显示绿色
              drawEdge(vData.edges[key].mesh, 0x00bb0f, topologyObject);
            } else {
              // 被引用2次以上，显示黄色
              drawEdge(vData.edges[key].mesh, 0xfdd421, topologyObject);
            }
          }
          ctx2.viewer.requestRender();
        }
      }
    }
    message.destroy();
    isChecked = true;
  } else {
    clearTopologyGroup();
    isChecked = false;
  }
};

const drawEdge = (mesh: number[], color: number, parent: Object3D) => {
  const vertexs: Vector3[] = [];
  for (let i = 0; i < mesh.length; i++) {
    vertexs.push(new Vector3(mesh[i][0], mesh[i][1], mesh[i][2]));
  }
  const line = new CSLine({
    vertexs: vertexs,
    lineWidth: 4,
    color: color,
  });
  parent.add(line);
};

export const cmdCheckTopology: BaseCommand = {
  id: 'CmdTopology',
  label: 'command.topology',
  icon: 'commands/common/topology-check',
  noHighlight: true,
  standalone: true,
  invoke: async () => {
    checkTopology();
  },
};
